package com.poi.demopoi.controller;

import com.poi.demopoi.domain.EmployeeVO;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;

public class Consumer extends Thread {
    private static final Logger log = LoggerFactory.getLogger(Consumer.class);

    private ArrayBlockingQueue<List<EmployeeVO>> queue;
    private Integer count;
    private Integer total;
    private SXSSFWorkbook sxssfWorkbook;
    private Integer times;

    public Consumer(ArrayBlockingQueue<List<EmployeeVO>> queue, SXSSFWorkbook sxssfWorkbook, Integer total) {
        this.queue = queue;
        this.total = total;
        this.count = 0;
        this.sxssfWorkbook = sxssfWorkbook;
        this.times = 1;
    }

    @Override
    public void run() {
        try {
            while (true) {
                if (count >= total) {
                    break;
                }
                log.info(String.format("消费者第[%s]次从队列中取出数据，准备写入Excel", this.times));
                Long dataWriteStartTS = System.currentTimeMillis();
                List<EmployeeVO> financeStatisticsDTOList = queue.take();
                log.info(String.format("消费者线程[%s]成功获取1W条数据，在队列阻塞：[%s]ms", this.getName(), System.currentTimeMillis() - dataWriteStartTS));

                //根据总条数 确定消费者 本次写入数据时的 sheet 和 开始行数             2 = 主标题+副标题
                int index = count % EmployeeController.MAX_ROW_SHEET == 0 ? (count + 2) : (count % EmployeeController.MAX_ROW_SHEET + 2);
                count += financeStatisticsDTOList.size();
                Integer sheetNum = count / EmployeeController.MAX_ROW_SHEET;

                Sheet sheet = sxssfWorkbook.getSheetAt(sheetNum);
                writeExcel(financeStatisticsDTOList, sheet, index);

                Long dataWriteEndTS = System.currentTimeMillis();
                log.info(String.format("消费者第[%s]次写入Excel完成，耗时%s ms", this.times, (dataWriteEndTS - dataWriteStartTS)));
                this.times++;
            }
        } catch (InterruptedException e) {
            log.error("消费者[%s]获取队列数据异常-->", e);
        }
    }

    private void writeExcel( List<EmployeeVO> financeStatisticsDTOList, Sheet sheet, Integer index) {
        if (CollectionUtils.isEmpty(financeStatisticsDTOList)) {
            log.info(String.format("消费者[%s]: 数据为空", this.getName()));
            return;
        }

        for (int i = 0; i < financeStatisticsDTOList.size(); i++) {
            Row row = sheet.createRow(index++);
            EmployeeVO statisticsDTO = financeStatisticsDTOList.get(i);

            //todo
            row.createCell(0).setCellValue(statisticsDTO.getId());
            row.createCell(1).setCellValue(statisticsDTO.getName());
            row.createCell(2).setCellValue(statisticsDTO.getAge());
            row.createCell(3).setCellValue(statisticsDTO.getEmail());
            //.....省略设置表格数据的代码
        }
        //处理完以后将数据引用置空便于GC
        financeStatisticsDTOList.clear();
    }
}
